package com.tanhua.server.service;

import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.*;
import com.tanhua.domain.vo.AnswerVo;
import com.tanhua.domain.vo.QuestionVo;
import com.tanhua.domain.vo.ReportVo;
import com.tanhua.domain.vo.SoulTestVo;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.SoulApi;
import com.tanhua.server.Cache.SoulCache;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SoulService {

    @Reference
    private SoulApi soulApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Autowired
    private SoulCache soulCache;

    //测灵魂-问卷列表
    public ResponseEntity<Object> testSoul() {
        Long id = UserHolder.getUserId();

        //因为问卷列表查多改少，可以使用缓存
        List<Questionnaire> questionnaireList = soulCache.findSoultest();
        //查询后台所有的问卷列表
        //然后根据这个问卷封装好SoulTestVo返回
        List<SoulTestVo> result = new ArrayList<>();
        //设置一个参数用于判断问卷是否被锁住
        Integer lock = 1;
        for (int i = 0; i < questionnaireList.size(); i++) {
            Questionnaire questionnaire = questionnaireList.get(i);
            SoulTestVo soulTestVo = new SoulTestVo();
            soulTestVo.setId(questionnaire.getId().toString());
            soulTestVo.setLevel(questionnaire.getLevel().toString());
            BeanUtils.copyProperties(questionnaire, soulTestVo);
            //从问卷中找到question的id，根据id找到question封装到questionVo
            List<Integer> questionsId = questionnaire.getQuestionsId();
            //根据questionsId一次性返回所有符合的question
            List<Question> questions = soulCache.findQuestionsByIdList(questionsId);
            //将数据封装到vo
            List<QuestionVo> questionVoList = new ArrayList<>();

            for (Question question : questions) {
                QuestionVo questionVo = new QuestionVo();
                questionVo.setId(question.getQid().toString());
                BeanUtils.copyProperties(question, questionVo);
                questionVoList.add(questionVo);
            }
            soulTestVo.setQuestions(questionVoList);
            //根据用户id查询在userevaluate这个表中的数据，来判断是否需要锁住
            UserEvaluate userEvaluate = soulApi.findUserEvaluateByIdAndQid(id, questionnaire.getId());
            //如果找不到，则未完成评级，找得到则完成评级
            String reportId ="0";
            if (userEvaluate == null) {
                userEvaluate = new UserEvaluate();
                userEvaluate.setUid(id.intValue());
                userEvaluate.setScore(0);
                userEvaluate.setLock(1);
                userEvaluate.setCid(0);
                userEvaluate.setQid(questionnaire.getId());
                soulApi.saveUserEvaluate(userEvaluate);
            } else {
                reportId = userEvaluate.getCid().toString();
            }
            //第一份问卷永远都不锁
            if (i == 0) {
                lock = 0;
            }
            soulTestVo.setIsLock(lock);
            //从userEvaluates根据问卷等级获取，如果有设置对应的分数
            soulTestVo.setReportId(reportId.equals("0")?null:reportId);
            result.add(soulTestVo);
            //根据本份问卷是否获得分数来判断下分问卷是否被锁住
            lock = userEvaluate.getScore() == 0 ? 1 : 0;
        }
        return ResponseEntity.ok(result);
    }


    //接测灵魂-提问卷
    public ResponseEntity<Object> submitSoul(AnswerVo[] answerVos) {
        Long id = UserHolder.getUserId();
        //根据提交的选项和答案算出总分
        Integer score = 0;
        for (AnswerVo answerVo : answerVos) {
            String questionId = answerVo.getQuestionId();
            String optionId = answerVo.getOptionId();
            //根据questionId找到对应的问题
            Question question = soulApi.findQuestionById(Integer.parseInt(questionId));
            List<Option> optionList = question.getOptions();
            for (Option option : optionList) {
                //获取对应的分值累加
                if (option.getId().equals(optionId)) {
                    score += Integer.parseInt(option.getScore());
                    break;
                }
            }
        }
        //根据任意一个题目id获取问卷号
        String questionId = answerVos[0].getQuestionId();
        Questionnaire questionnaire = soulApi.findQuestionnaire(Long.parseLong(questionId));
        //根据用户id修改分值
        //先查询用户结论
        UserEvaluate userEvaluate = soulApi.findUserEvaluateById(id);
        userEvaluate.setScore(score);
        userEvaluate.setQid(questionnaire.getId());
        //并将该问卷状态改为0
        userEvaluate.setLock(0);
        //获取问卷号，根据问卷号找到对应的结论id
        List<Integer> conclusionsId = questionnaire.getConclusionsId();
        String reportCid = "0";
        for (Integer cid : conclusionsId) {
            //找到对应的结论
            Conclusion conclusion = soulApi.findConclusionsById(cid);
            //然后根据总分判断数据应该返回哪个结论cid
            Integer upper = conclusion.getUpper();//获得分值上限
            Integer floor = conclusion.getFloor();//获得分值下限
            if (score >= floor && score <= upper) {
                userEvaluate.setCid(cid);
                reportCid = cid.toString();
                break;
            }
        }
        soulApi.updateUserEvalute(userEvaluate);
        return ResponseEntity.ok(reportCid);
    }

    //测灵魂-查看结果
    public ResponseEntity<Object> showReport(Integer cid) {
        //首先根据cid找到对应的结论
        Conclusion concluson = soulCache.findConclusionsById(cid);
        ReportVo reportVo = new ReportVo();
        BeanUtils.copyProperties(concluson, reportVo);
        //封装所有数据
        List<Map<String, Object>> similarYou = new ArrayList<>();
        //根据传递的cid获得其他相近的用户。顺便排除自己
        List<UserEvaluate> userEvaluates = soulApi.findUserEvaluateByCId(cid, UserHolder.getUserId());
        if (!CollectionUtils.isEmpty(userEvaluates)) {
            for (UserEvaluate userEvaluate : userEvaluates) {
                UserInfo userInfo = userInfoApi.findById(userEvaluate.getUid().longValue());
                Map<String, Object> map = new HashMap<>();
                map.put("id", userInfo.getId().intValue());
                map.put("avatar", userInfo.getAvatar());
                similarYou.add(map);
            }
        }
        //根据用户id获得头像
        reportVo.setSimilarYou(similarYou);
        return ResponseEntity.ok(reportVo);
    }


}
